#ifndef __WIZ_STATIC_HPP__SHANHAOBO_19800429__
#define __WIZ_STATIC_HPP__SHANHAOBO_19800429__

#include "../Base/WizBase.hpp"

#include "./WizInterlocked.hpp"
#include "./WizCallOnce.hpp"

namespace Wiz
{
    namespace Static
    {
        template<class StorageT, class TagT>
        struct Type : ::Wiz::Noncopyable::Type
        {
        private:
            struct Destructor_t
            {
                ~Destructor_t()
                {
                    Type::GetAddress()->~StorageT();
                }
            };
            struct DefaultCtor_t
            {
                static ::Wiz::Void::Type Construct()
                {
                    ::new (Type::GetAddress()) StorageT();
                    static Destructor_t d;
                }
            };
        public:
            typedef ::Wiz::Byte::Type tStorage[sizeof(StorageT)];
            static tStorage                     m_Data;
            static ::Wiz::CallOnce::Flag::Type  m_Flag;
            typedef typename ::Wiz::TypeTraits::Get::Reference<StorageT>::tType       tReference;
            typedef typename ::Wiz::TypeTraits::Get::ReferenceConst<StorageT>::tType  tReferenceConst;
            Type(TagT = TagT())
            {
                ::Wiz::CallOnce::Do(m_Flag, DefaultCtor_t::Construct);
            }
            ~Type()
            {

            }
        public:
            operator tReference()
            {
                return this->Get();
            }

            operator tReferenceConst() const
            {
                return this->Get();
            }

            tReference Get()
            {
                return *this->GetAddress();
            }

            tReferenceConst Get() const
            {
                return *this->GetAddress();
            }
        public:
            static StorageT* GetAddress()
            {
                return reinterpret_cast<StorageT*>(&(m_Data[0]));
            }
        }; /// end of struct Type

        template <class StorageT, class TagT>
        typename Type<StorageT, TagT>::tStorage Type<StorageT, TagT>::m_Data;
        template <class StorageT, class TagT>
        ::Wiz::CallOnce::Flag::Type Type<StorageT, TagT>::m_Flag = ::Wiz::CallOnce::Flag::Init;
    } /// end of namespace Static
} /// end of namespace Wiz

#endif /*__WIZ_STATIC_HPP__SHANHAOBO_19800429__*/
